(**********************************************************************

    :Program.    TrackDiskSupport.def
    :Contents.   Support to access trackdisk/hddisk sectors
    :Author.     Fridtjof Siebert [fbs]
    :Address.    [fbs] Nobileweg 67, D7000 Stuttgart 40
    :Phone.      [fbs] (0)711/822509
    :Author.     Nicolas Benezan [bne]
    :Address.    [bne] Postwiesenstr. 2, D7000 Stuttgart 60
    :Phone.      [bne] 0711/333679
    :Copyright.  Public Domain, no commercial use !!!
    :Language.   Modula-2
    :Translator. M2Amiga A+L V3.2d
    :Imports.    DosSupport1.3, TaskMemory [bne]
    :History.    V1.0 [fbs] 5.Dez.1988
    :History.    V1.1 [bne] 12.May.1989 (adapted m2c V3.2d)
    :History.    V2.0 [bne] 13.May.1989 (+ other drivetypes, DHx: etc.)
    :History.    V2.1 [bne] 14.May.1989 (+ InhibitDrive, bugs fixed)

**********************************************************************)
DEFINITION MODULE TrackDiskSupport;

FROM Dos         IMPORT ProcessId;
FROM DosSupport  IMPORT DiskInfoPtr;
FROM Exec        IMPORT Byte;
FROM SYSTEM      IMPORT ADDRESS, LONGSET;

TYPE
  DiskUnit;
  Name=ARRAY [0..31] OF CHAR;
  DeviceInfo=RECORD
    devName:Name;        (* example: "trackdisk.device" *)
    devUnit:LONGINT;     (* unit number *)
    devFlags:LONGSET;    (* flags for OpenDevice() *)
    blockLen:LONGINT;    (* bytes per block *)
    trackLen:LONGINT;    (* bytes per track *)
    cylinderLen:LONGINT; (* bytes per cylinder *)
    numBlocks:LONGINT;   (* total number of blocks per disk or partition *)
    offset:LONGINT;      (* offset for partition origin *)
    disk:DiskInfoPtr;    (* MountList entries, e.g. LowCyl HighCyl... *)
    handler:ProcessId;   (* Dos file handler process *)
  END;

VAR
  TrackDiskAllocProc:PROCEDURE(VAR ADDRESS,LONGINT);
  TrackDiskDeallocProc:PROCEDURE(VAR ADDRESS);

PROCEDURE OpenDiskDevice(    DeviceName: ARRAY OF CHAR;
                         VAR Unit: DiskUnit): Byte;

(*:Input.    DeviceName: Name of the devive (examples: "DF1", "DH0", "JH0")
  :Output.   Unit: internal data structure to handle this device unit
  :Result.   Error number or 0 if successfully
  :Semantic. Determines which device and unit is responsible for the
  :Semantic. specified drive and opens it.
*)

PROCEDURE CloseDiskDevice(Unit: DiskUnit);

(*:Input.    Unit: successfully opened DiskUnit (via OpenDiskDevice)
  :Semantic. Closes a disk device unit.
*)

PROCEDURE GetDeviceInfo(    Unit: DiskUnit;
                        VAR Info: DeviceInfo);

(*:Input.    Unit: successfully opened DiskUnit (via OpenDiskDevice)
  :Output.   Info: Information about that device (LowCyl, HighCyl and so on)
*)

PROCEDURE GetDiskChange(Unit: DiskUnit): LONGINT;

(*:Input.    Unit: successfully opened DiskUnit (via OpenDiskDevice)
  :Result.   Disk Change number (necessary to detect disk changes)
*)

PROCEDURE ChangeState(Unit: DiskUnit): BOOLEAN;

(*:Input.    Unit: successfully opened DiskUnit (via OpenDiskDevice)
  :Result.   TRUE if disk inserted, else FALSE
*)

PROCEDURE ProtStatus(Unit: DiskUnit): BOOLEAN;

(*:Input.    Unit: successfully opened DiskUnit (via OpenDiskDevice)
  :Result.   TRUE if write enabled
*)

PROCEDURE Motor(Unit: DiskUnit; On: BOOLEAN): BOOLEAN;

(*:Input.    Unit: successfully opened DiskUnit (via OpenDiskDevice)
  :Input.    On: turm Motor on (TRUE) or off (FALSE)
  :Result.   old motor state: TRUE = on, FALSE = off
  :Semantic. Turns motor on or off according to <On>.
*)

PROCEDURE Seek(Unit: DiskUnit; BlockNum: LONGINT): Byte;

(*:Input.    Unit: successfully opened DiskUnit (via OpenDiskDevice)
  :Input.    BlockNum: where to seek to. Must be a multiple of
  :Input.              surfaces * numSecs
  :Output.   Error number or 0 if successful
  :Semantic. Moves head to specified track
  :Note.     WARNING: surfaces and numSecs depend on the drive type
  :Note.     (harddisks...) and mut be determined by GetDeviceInfo()!!!
*)

PROCEDURE BlockNumber(Unit: DiskUnit;
                      Cylinder, Sector, Head: LONGINT): LONGINT;

(*:Input.    Unit: successfully opened DiskUnit (via OpenDiskDevice)
  :Input.    Cylinder, Sector, Head: location of the block on disk
  :Result.   logical number of that block (for ReadBlock or WriteBlock)
*)

PROCEDURE ReadBlock(Unit: DiskUnit;
                    Block: LONGINT;
                    NumBlocks: CARDINAL;
                    Buffer: ADDRESS;
                    ChangeCnt: LONGINT): Byte;

(*:Input.    Unit: successfully opened DiskUnit (via OpenDiskDevice)
  :Input.    Block:    number of the first block to be read
  :Input.    NumBlocks:how many blocks to be read
  :Input.    Buffer:   at least 512 Bytes of Chip memory to store data
  :Input.    ChangeCnt:last changenumber to check diskchanges
  :Result.   error number or 0 if successful
  :Semantic. Reads BlockCnt Blocks from Disk
*)

PROCEDURE WriteBlock(Unit: DiskUnit;
                     Block: LONGINT;
                     NumBlocks: CARDINAL;
                     Buffer: ADDRESS;
                     ChangeCnt: LONGINT): Byte;

(*:Input.    Unit: successfully opened DiskUnit (via OpenDiskDevice)
  :Input.    Block:    number of the first block to be read
  :Input.    NumBlocks:how many blocks to be read
  :Input.    Buffer:   at least 512 Bytes of Chip memory to store data
  :Input.    ChangeCnt:last changenumber to check diskchanges
  :Result.   error number or 0 if successful
  :Semantic. Writes BlockCnt Blocks to Disk
*)

PROCEDURE Update(Unit: DiskUnit;
                 ChangeCnt: LONGINT): Byte;

(*:Input.    Unit: successfully opened DiskUnit (via OpenDiskDevice)
  :Input.    ChangeCnt: last changenumber to check diskchanges
  :Result.   error number or 0 if successful
  :Semantic. Forces buffers to be written to disk (flush buffers)
*)

PROCEDURE FormatTrack(Unit: DiskUnit;
                      Cylinder: CARDINAL;
                      Head: CARDINAL;
                      Buffer: ADDRESS;
                      ChangeCnt: LONGINT): Byte;

(*:Input.    Unit: successfully opened DiskUnit (via OpenDiskDevice)
  :Input.    Cylinder, Head: location of the track to be formatted
  :Input.    Buffer: Buffer containing numSecs*sector bytes of data
  :Input.    ChangeCnt: last changenumber to check diskchanges
  :Result.   error number or 0 if successful
  :Semantic. Writes whole track to disk
*)

PROCEDURE Clear(Unit: DiskUnit): Byte;

(*:Input.    Unit: successfully opened DiskUnit (via OpenDiskDevice)
  :Result.   error number or 0 if successful
  :Semantic. Marks trackbuffer as invalid --> avoids rewriting it
*)

PROCEDURE GetDriveType(Unit: DiskUnit): LONGINT;

(*:Input.    Unit: successfully opened DiskUnit (via OpenDiskDevice)
  :Result.   1 means 3.5 inch drive connected, 2 means 5.25 inch drive,
  :Result.   other values mean non-standard drives.
  :Note.     WARNING: This command is defined for trackdisk.devices only !
  :Note.     Use GetDeviceInfo() to examine hd-partition's characteristics!
*)

PROCEDURE GetNumTracks(Unit: DiskUnit): LONGINT;

(*:Input.    Unit: successfully opened DiskUnit (via OpenDiskDevice)
  :Result.   total number of tracks the drive has
  :Note.     WARNING: This command is defined for trackdisk.devices only !
  :Note.     Use GetDeviceInfo() to examine HD-partition's characteristics!
*)

PROCEDURE InhibitDrive(Unit: DiskUnit;
                       Inhibit: BOOLEAN): BOOLEAN;

(*:Input.    Unit: successfully opened DiskUnit (via OpenDiskDevice)
  :Input.    Inhibit: TRUE: FileSystem is stopped from acessing this drive
  :Input.             FALSE: Access is re-enabled
  :Semantic. With this Command, you can stop Dos (FileSystem, DiskValidator)
  :Semantic. from accessing a specific disk drive. The Workbench will
  :Semantic. display "DFx:BUSY", CLI will report "Not a Dos disk" and so on.
  :Semantic. This is useful if you write programms such as "DiskCopy".
  :Result.   TRUE if ok, FALSE if an error occured
  :Note.     More Details about an error can be obtained via Dos.IoErr().
*)

END TrackDiskSupport.
